package cytj.setup.bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import cytj.setup.base.MessageWhat;
import cytj.setup.base.MyAPP;
import cytj.setup.util.CharacterTool;


/**
 * 蓝牙操作相关类
 * Created by LTP on 2015/12/18
 */
public class BluetoothService {
    /**
     * 调试用的TAG
     */
    private static final String TAG = "LTP";

    /**
     * 蓝牙的UUID
     */
    private static final UUID MY_UUID =
            UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private BluetoothAdapter mBluetoothAdapter;
    private Handler mHandler;
    private BluetoothConnectThread mBluetoothConnectThread;
    private BluetoothIOThread mBluetoothIOThread;

    /**
     * 构造方法
     *
     * @param handler Handler对象
     */
    public BluetoothService(Handler handler) {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mHandler = handler;
    }


    /**
     * 开始连接蓝牙设备
     *
     * @param device 要连接的蓝牙设备
     */
    public synchronized void connect(BluetoothDevice device) {
        Log.d(TAG, "连接到: " + device);

        // 开启连接线程前先终止所有准备连接的线程
        if (mBluetoothConnectThread != null) {
            mBluetoothConnectThread.cancel();
            mBluetoothConnectThread = null;
        }

        // 开启连接线程前先终止所有蓝牙读写的线程
        if (mBluetoothIOThread != null) {
            mBluetoothIOThread.cancel();
            mBluetoothIOThread = null;
        }

        // 开起蓝牙连接的线程
        mBluetoothConnectThread = new BluetoothConnectThread(device);
        mBluetoothConnectThread.start();
    }

    /**
     * 开启蓝牙读写线程
     *
     * @param bluetoothSocket 蓝牙Socket对象
     */
    public synchronized void startBluetoothIOThread(BluetoothSocket bluetoothSocket) {

        // 倘若存在正在连接的线程先取消掉
        if (mBluetoothConnectThread != null) {
            mBluetoothConnectThread.cancel();
            mBluetoothConnectThread = null;
        }

        // 倘若存在正在读写的线程先取消掉
        if (mBluetoothIOThread != null) {
            mBluetoothIOThread.cancel();
            mBluetoothIOThread = null;
        }

        // 开启蓝牙读写线程
        mBluetoothIOThread = new BluetoothIOThread(bluetoothSocket);
        mBluetoothIOThread.start();
    }

    /**
     * 关闭所有线程
     */
    public synchronized void stop() {
        if (mBluetoothConnectThread != null) {
            mBluetoothConnectThread.cancel();
            mBluetoothConnectThread = null;
        }

        if (mBluetoothIOThread != null) {
            mBluetoothIOThread.cancel();
            mBluetoothIOThread = null;
        }
        MyAPP.getMyAPPInstance().setIsBluetoothConnected(false);
    }

    /**
     * 采用同步的方式写数据
     *
     * @param out The bytes to write
     */
    public void write(byte[] out) {
        BluetoothIOThread tempBluetoothIOThread;
        synchronized (this) {
            if (!MyAPP.getMyAPPInstance().isBluetoothConnected()) return;
            tempBluetoothIOThread = mBluetoothIOThread;
        }
        tempBluetoothIOThread.write(out);
    }


    /**
     * 蓝牙连接的线程
     */
    private class BluetoothConnectThread extends Thread {
        private final BluetoothSocket mmBluetoothSocket;

        public BluetoothConnectThread(BluetoothDevice bluetoothDevice) {
            BluetoothSocket tempBluetoothSocket = null;
            try {
                tempBluetoothSocket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mmBluetoothSocket = tempBluetoothSocket;
        }

        public void run() {
            // 要先取消扫描，否则会使连接速度减慢
            mBluetoothAdapter.cancelDiscovery();
            try {
                //阻塞式方法
                mmBluetoothSocket.connect();
                mHandler.sendEmptyMessage(MessageWhat.CONNECT_BLUETOOTH_SUCCESS);
            } catch (IOException e) {
                // 发生异常即连接失败，就发送蓝牙连接失败的消息并关闭Socket
                mHandler.sendEmptyMessage(MessageWhat.CONNECT_BLUETOOTH_FAILED);
                // 出现异常断开Socket连接
                try {
                    mmBluetoothSocket.close();
                } catch (IOException e2) {
                    Log.e(TAG, "异常后无法关闭Socket连接");
                }
                return;
            }

            // Reset the ConnectThread because we're done
            synchronized (BluetoothService.this) {
                mBluetoothConnectThread = null;
            }

            // 开启读写线程
            startBluetoothIOThread(mmBluetoothSocket);
        }

        public void cancel() {
            try {
                mmBluetoothSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 蓝牙读写线程
     */
    private class BluetoothIOThread extends Thread {
        private final BluetoothSocket mmBluetoothSocket;
        private final InputStream mmInputStream;
        private final OutputStream mmOutputStream;
        private String firstByteStr = "";

        public BluetoothIOThread(BluetoothSocket socket) {
            mmBluetoothSocket = socket;
            InputStream tmpInputStream = null;
            OutputStream tmpOutputStream = null;

            // 获取蓝牙Socket的输入输出流
            try {
                tmpInputStream = socket.getInputStream();
                tmpOutputStream = socket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG, "temp sockets not created", e);
            }

            mmInputStream = tmpInputStream;
            mmOutputStream = tmpOutputStream;
        }

        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;

            // 循环读取
            while (true) {
                try {
                    bytes = mmInputStream.read(buffer);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    String readString = CharacterTool.BytesToHexString(buffer, bytes);
                    if (readString.length() == 2) {
                        firstByteStr = readString;
                    } else {
//                        if (readString.substring(0, 2).equalsIgnoreCase("AA")) {
//                            readString = "AA" + readString;
//                        } else if (readString.substring(0, 2).equalsIgnoreCase("AB")) {
//                            readString = "AB" + readString;
//                        }
                        readString = firstByteStr + readString;
                        firstByteStr = "";
                        String splitData = CharacterTool.splitData(readString);
                        Log.d(TAG, "收到:" + splitData);
                        mHandler.obtainMessage(MessageWhat.DATA_RECEIVED_SUCCESS, splitData).sendToTarget();
                    }
                    List<String> strLists = new ArrayList<>();
                    for (int i = 0; i < readString.length() - 4; i += 2) {
                        if (readString.substring(i, i + 4).equalsIgnoreCase("AAAA")) {
                            strLists.add(readString.substring(i));
                        }
                    }
                    for (String str : strLists) {
                        Log.d(TAG, "截取到AAAA的数据：" + CharacterTool.splitData(str));
                        if (str.length() > 12 && CharacterTool.xor(CharacterTool.hexStringToBytes(str), str.length() / 2).equals("00")) {
                            String func = str.substring(10, 12);
                            Log.d(TAG, "功能码" + func);
                            if ("DE".equalsIgnoreCase(func)) {
                                Log.d(TAG, "截取到功能码为DE(读取基站配置信息成功)的数据：" + CharacterTool.splitData(str));
                                mHandler.obtainMessage(MessageWhat.READ_BASE_DATA_SUCCESS, str).sendToTarget();
                            } else if ("DF".equalsIgnoreCase(func)) {
                                Log.d(TAG, "截取到功能码为DF(写入基站配置信息成功)的数据：" + CharacterTool.splitData(str));
                                mHandler.sendEmptyMessage(MessageWhat.WRITE_BASE_DATA_SUCCESS);
                            } else if ("F0".equalsIgnoreCase(func)) {
                                if (str.length() == 24) {
                                    Log.d(TAG, "截取到功能码为F0(部署节点时获取基站ID成功)的长数据：" + CharacterTool.splitData(str));
                                }
                                if (str.length() == 22) {
                                    Log.d(TAG, "截取到功能码为F0(部署节点时获取节点ID成功)的短数据：" + CharacterTool.splitData(str));
                                }
                                mHandler.obtainMessage(MessageWhat.DEPLOY_BASE_COMMUNICATION_SUCCESS, str).sendToTarget();
                            } else if ("F1".equalsIgnoreCase(func)) {
                                Log.d(TAG, "截取到功能码为F1(节点部署成功)的数据：" + CharacterTool.splitData(str));
                                mHandler.obtainMessage(MessageWhat.DEPLOY_NODES_SUCCESS, str).sendToTarget();
                            } else if ("80".equalsIgnoreCase(func)) {
                                Log.d(TAG, "截取到功能码为80(设定节点休眠成功)的数据：" + CharacterTool.splitData(str));
                                mHandler.obtainMessage(MessageWhat.SET_NODES_SLEEP_SUCCESS, str).sendToTarget();
                            } else if ("81".equalsIgnoreCase(func)) {
                                Log.d(TAG, "截取到功能码为81(重启节点成功)的数据：" + CharacterTool.splitData(str));
                                mHandler.obtainMessage(MessageWhat.RESTART_NODES_SUCCESS, str).sendToTarget();
                            } else if ("82".equalsIgnoreCase(func)) {
                                Log.d(TAG, "截取到功能码为82(更改节点停车状态成功)的数据：" + CharacterTool.splitData(str));
                                mHandler.obtainMessage(MessageWhat.CHANGE_NODES_STATUS_SUCCESS, str).sendToTarget();
                            }
                        }
                    }
                } catch (IOException e) {
                    Log.e(TAG, "disconnected");
                    //发生异常即连接意外断开，便通知UI断开以及更改蓝牙连接状态
                    mHandler.sendEmptyMessage(MessageWhat.BLUETOOTH_CONNECTION_LOST);
                    break;
                }
            }
        }

        /**
         * 蓝牙写字节数据.
         *
         * @param buffer 字节数组
         */
        public void write(byte[] buffer) {
            try {
                mmOutputStream.write(buffer);
            } catch (IOException e) {
                Log.e(TAG, "蓝牙发送数据失败！");
                e.printStackTrace();
            }
        }

        public void cancel() {
            try {
                mmBluetoothSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "关闭蓝牙Socket失败");
                e.printStackTrace();
            }
        }
    }
}
